package com.hskn.hss.filter;

import com.alibaba.fastjson.JSONObject;
import com.hskn.hss.aop.RequestReaderHttpServletRequestWrapper;
import com.hskn.hss.core.utils.spring.SpringUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.service.impl.UserServiceImpl;
import com.hskn.hss.utils.JedisPoolUtils;
import com.hskn.hss.utils.StringUtils;
import com.hskn.hss.utils.Tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;

@Slf4j
@Component
public class UserAuthorizationFilter implements Filter {

    private static final String TICKET = "ticket";
    private static final String JURISDICTION = "jurisdiction";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        String url = request.getRequestURI();
        if (url.contains("loginByPwd") ||
                url.contains("imserver") ||
                url.contains("common") ||
                url.contains("sysinfo/detail") ||
                url.contains("swagger") ||
                url.contains("webjars") ||
                url.contains("v2")) {
            filterChain.doFilter(request, response);
        } else {
            String ticket = getTicket(request, TICKET);
            String jurisdiction = getTicket(request, JURISDICTION);
            if (StringUtils.isNotEmpty(ticket)) {
                Jedis jedis = null;
                try {
                    //校验ticket是否过期
                    jedis = JedisPoolUtils.getJedis();
                    String existJedis = jedis.get(ticket);
                    if (StringUtils.isEmpty(existJedis)) {
                        AjaxResult<Object> ajaxResult = AjaxResult.fail("用户身份无效、无权限访问，请重新登录.", 300);
                        response.getWriter().println(JSONObject.toJSONString(ajaxResult));
                    } else {
                        if (ticket.contains("%")) {
                            ticket = URLDecoder.decode(ticket, "UTF-8");
                        }
                        JSONObject ticketObj = Tools.getUser4Ticket(ticket);

                        if (null != ticketObj) {
                            JSONObject userInfo = new JSONObject();
                            userInfo.put("uid", ticketObj.get("uid"));
                            userInfo.put("account", ticketObj.get("account"));
                            request.getSession().setAttribute("userInfo", userInfo);
                            request.setAttribute("ticketFromFilter", ticket);
                            User loginUser = SpringUtils.getBean(UserServiceImpl.class)
                                    .getUserDetail(ticketObj.getString("uid"));
                            //TODO  按钮权限验证暂时注释
//                            List<SysMenu> sysMenuList = null;
//                            if (loginUser.getIsAdmin()!=1) {
//                                if (StringUtils.isNotEmpty(url)) {
//                                    List<SysButton>  sysButtonList = SpringUtils.getBean(SysButtonServiceImpl.class)
//                                            .selectList(new QueryWrapper<SysButton>().lambda().eq(SysButton::getAction,jurisdiction));
//                                    List<String> menuIdList = sysButtonList.stream().map(SysButton::getMenuid).collect(Collectors.toList());
//                                    QueryWrapper<SysMenu> sysMenuQueryWrapper = new QueryWrapper<SysMenu>();
//                                    if (CollectionUtils.isNotEmpty(menuIdList)) {
//                                        sysMenuQueryWrapper.lambda().in(SysMenu::getId
//                                                ,menuIdList);
//                                    }
//                                    sysMenuQueryWrapper.lambda().or().eq(SysMenu::getAction,url);
//                                    sysMenuList = SpringUtils.getBean(SysMenuServiceImpl.class)
//                                            .selectList(sysMenuQueryWrapper);
//                                }
//
//                                if(CollectionUtils.isEmpty(sysMenuList)){
//                                    AjaxResult<Object> ajaxResult = AjaxResult.fail("用户身份无效、无权限访问.", 301);
//                                    response.getWriter().println(JSONObject.toJSONString(ajaxResult));
//                                }else {
//                                    filterChain.doFilter(request, response);
//                                }
//                            }else {
                            ServletRequest requestWrapper = null;
                            String contentType = request.getContentType();
                            if (request instanceof HttpServletRequest && StringUtils.isNotEmpty(contentType) && contentType.indexOf("application/json") != -1) {
                                requestWrapper = new RequestReaderHttpServletRequestWrapper(request);
                            }
                            //获取请求中的流如何，将取出来的字符串，再次转换成流，然后把它放入到新request对象中。
                            // 在chain.doFiler方法中传递新的request对象
                            if (requestWrapper == null) {
                                filterChain.doFilter(request, response);
                            } else {
                                filterChain.doFilter(requestWrapper, response);
                            }
//                                filterChain.doFilter(request, response);
//                            }
                        } else {
                            AjaxResult<Object> ajaxResult = AjaxResult.fail("用户身份无效、无权限访问，请重新登录.", 300);
                            response.getWriter().println(JSONObject.toJSONString(ajaxResult));
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    log.error(e.getMessage(), e);
                } finally {
                    if (jedis != null) {
                        jedis.close();
                    }
                }
            } else {
                AjaxResult<Object> ajaxResult = AjaxResult.fail("用户身份无效、无权限访问，请重新登录.", 300);
                response.getWriter().println(JSONObject.toJSONString(ajaxResult));
            }
        }
    }

    @Override
    public void destroy() {

    }

    /**
     * 获取ticket
     *
     * @param request    ServletRequest
     * @param ticketName String
     * @return ticket String
     */
    private String getTicket(ServletRequest request, String ticketName) {
        String ticket = "";

        // 从session中获取
        ticket = (String) ((HttpServletRequest) request).getSession().getAttribute(ticketName);
        if (null != ticket && !"".equals(ticket)) {
            return ticket;
        }

        // 从url中获取
        String queryStr = ((HttpServletRequest) request).getQueryString();
        if (null != queryStr && queryStr.indexOf(ticketName) >= 0) {
            String paramStr = queryStr.substring(queryStr.indexOf(ticketName + "=") + ticketName.length() + 1);
            if (null != paramStr) {
                if (paramStr.indexOf("&") > -1) {
                    ticket = paramStr.substring(0, paramStr.indexOf("&"));
                } else {
                    ticket = paramStr;
                }
            }
            return ticket;
        }

        // 从cookies中获取
        Cookie[] cookies = ((HttpServletRequest) request).getCookies();
        Cookie ticketCookie = null;
        if (cookies != null) {
            for (Cookie cc : cookies) {
                if (cc.getName().equals(ticketName)) {
                    ticketCookie = cc;
                    break;
                }
            }
        }
        if (null != ticketCookie) {
            ticket = ticketCookie.getValue();
            return ticket;
        }

        // 从请求头里获取
        ticket = ((HttpServletRequest) request).getHeader(ticketName);
        return ticket;
    }
}
